using abilities.parameters;
using abilities.templates;
using UnityEngine;

namespace abilities.effects
{
    enum EffectParameterIncrement
    {
        IncrementAbsolute,
        IncrementRelative
    }

    /**参数
*  {
*    "type" : "PARAMETER_MODIFIER",
*    "parameter" : "HEALTH",
*    "increment" : "ABSOLUTE",
*    "delta" : 10
*  }
*/
    public class EffectParameterModifier : Effect<EffectParameterModifierTemplate>
    {
        ParameterEntry _parameterEntry;


        int deltaInt;
        int deltaBaseParameter;
        int deltaCurrentParameter;
        EffectParameterIncrement incrementType;
        
        public EffectParameterModifier(EffectParameterModifierTemplate t,int level) : base(t,level)
        {
            incrementType = EffectParameterIncrement.IncrementAbsolute;
        }
        

        protected override void OnInit(EffectParameterModifierTemplate proto,int lv)
        {
            _parameterEntry = ParameterEntry.GetByName(proto.parameter);
            deltaInt = proto.GetDelta(lv);

            if (proto.increment == "RELATIVE")
            {
                incrementType = EffectParameterIncrement.IncrementRelative;
            }
            else
            {
                incrementType = EffectParameterIncrement.IncrementAbsolute;
            }

            deltaBaseParameter = 0;
            deltaCurrentParameter = 0;
        }


        protected override void Apply(UnitObject view, bool replay)
        {
            if (replay)
            {
                return;
            }

            Debug.Log("apply %p" + this);
            if (_parameterEntry == ParameterEntry.DAMAGE && view.Parameter.GetBase(_parameterEntry) < 0)
            {
                //值不应该改变。
                return;
            }

            if (!template.onlyCurrent)
            {
                applyBaseAndCurrent(view);
            }
            else
            {
                applyOnlyCurrent(view);
            }
        }

        protected override void Cancel(UnitObject view, bool replay)
        {
            if (replay)
            {
                return;
            }

            if (view.isDead())
            {
                return;
            }

            Debug.Log("cancel %p" + this);
            int baseParamToChange = 0;
            int currentParamToChange = 0;
            if (!template.onlyCurrent)
            {
                //取消基本价值,当前可以在ParameterValue.deltaCurrent
                baseParamToChange = -deltaBaseParameter;
            }

            if (template.restoreOnCancel)
            {
                currentParamToChange = -deltaCurrentParameter;
            }

            changeParameter(view, baseParamToChange, currentParamToChange);
        }


        void applyBaseAndCurrent(UnitObject view)
        {
            int articleBaseValue = 0;
            articleBaseValue = view.Parameter.GetBase(_parameterEntry);

            int currentBaseValue = view.Parameter.GetBase(_parameterEntry);
            int currentCurrentValue = view.Parameter.GetCurrent(_parameterEntry);
            int deltaBase = 0;
            int deltaCurrent = 0;

            if (template.settingDirectly)
            {
                if (incrementType == EffectParameterIncrement.IncrementRelative)
                {
                    deltaBase = (int) (articleBaseValue * deltaInt / 100.0f - currentBaseValue);
                    deltaCurrent = (int) (deltaInt / 100.0f * currentBaseValue - currentCurrentValue);
                }
                else if (incrementType == EffectParameterIncrement.IncrementAbsolute)
                {
                    deltaBase = deltaInt - currentBaseValue;
                    deltaCurrent = deltaInt - currentCurrentValue;
                }
            }
            else
            {
                if (incrementType == EffectParameterIncrement.IncrementRelative)
                {
                    // 按百分比提高基本值和当前值
                    deltaBase = deltaCurrent = (int) (deltaInt / 100.0f * articleBaseValue);
                }
                else if (incrementType == EffectParameterIncrement.IncrementAbsolute)
                {
                    //同时提高基本值和当前值
                    deltaBase = deltaInt;
                    deltaCurrent = Mathf.Max(0, deltaInt);
                }
            }

            if (currentBaseValue != 0 && currentBaseValue + deltaBase <= 0)
                deltaBase -= currentBaseValue + deltaBase - 1;
            if (currentCurrentValue != 0 && currentCurrentValue + deltaCurrent <= 0)
                deltaCurrent -= currentCurrentValue + deltaCurrent - 1;

            changeParameter(view, deltaBase, deltaCurrent);
            deltaBaseParameter += view.Parameter.GetBase(_parameterEntry) - currentBaseValue;
            deltaCurrentParameter += view.Parameter.GetCurrent(_parameterEntry) - currentCurrentValue;
        }

        void applyOnlyCurrent(UnitObject view)
        {
            int deltaCurrent = 0;
            int currentCurrentValue = view.Parameter.GetCurrent(_parameterEntry);

            if (template.settingDirectly)
            {
                if (incrementType == EffectParameterIncrement.IncrementRelative)
                {
                    deltaCurrent = (int) (deltaInt / 100.0f * view.Parameter.GetBase(_parameterEntry) - currentCurrentValue);
                }
                else if (incrementType == EffectParameterIncrement.IncrementAbsolute)
                {
                    deltaCurrent = deltaInt - currentCurrentValue;
                }
            }
            else
            {
                if (incrementType == EffectParameterIncrement.IncrementRelative)
                {
                    //按百分比提高基本值和当前值
                    deltaCurrent = (int) (deltaInt / 100.0f * currentCurrentValue);
                }
                else if (incrementType == EffectParameterIncrement.IncrementAbsolute)
                {
                    //同时提高基本值和当前值
                    deltaCurrent = deltaInt;
                }
            }

            changeParameter(view, 0, deltaCurrent);
            deltaCurrentParameter += view.Parameter.GetCurrent(_parameterEntry) - currentCurrentValue;
        }


        void changeParameter(UnitObject view, int deltaBase, int deltaCurrent)
        {
            if (deltaBase == 0 && deltaCurrent == 0)
            {
                return;
            }

            int newBase = view.Parameter.DeltaBase(_parameterEntry, deltaBase);
            if (_parameterEntry == ParameterEntry.HEALTH)
            {
                Debug.Log($"changeParameter {view} {deltaBase} {deltaCurrent} => {newBase}");
            }
        }
    }
}